/*
npm i koa koa2-cors @koa/router koa-bodyparser
pkg -t node16-win-x64 full.js
访问
http://127.0.0.1:3000/call?cli=0
*/
const Koa = require("koa");
const Router = require("@koa/router");
const bodyParser = require("koa-bodyparser");
const cors = require("koa2-cors");
const { exec } = require("child_process");
const fs = require("fs");
const path = require("path");

const multer = require('koa-multer');
const os = require("os"); 
var ips = Object.values(os.networkInterfaces()).flat().filter(e=>!e.internal && e.family === "IPv4").map(e=>e.address)
 
// 手动创建一个返回 Promise 的函数来包装 exec
function execAsync(command) {
  return new Promise((resolve, reject) => {
    exec(command, (error, stdout, stderr) => {
      console.log(error, stdout, stderr);
      if (error) {
        reject(error);
      } else {
        resolve(stdout + stderr);
      }
    });
  });
}

// 获取所有可用盘符
function getAvailableDrives() {
  const drives = [];
  for (let i = 65; i <= 90; i++) { 
    const drive = String.fromCharCode(i) + ":\\";
    try {
      if (fs.readdirSync(drive)) { 
        drives.push(drive);
      }
    } catch (err) { 
    }
  }
  return drives;
}

// 递归遍历目录的函数，同步版本
function traverseDirectorySync(directory, targetFile) {
  try {
    const dirents = fs.readdirSync(directory, { withFileTypes: true });
    for (const dirent of dirents) {
      const fullPath = path.join(directory, dirent.name);
      if (dirent.isDirectory()) { 
        if (
          dirent.name.startsWith(".") ||
          dirent.name === "tmp" ||
          dirent.name === "node_modules"
        ) {
          continue; // 跳过该文件夹
        }
        // 如果是文件夹，递归调用
        const result = traverseDirectorySync(fullPath, targetFile);
        if (result) {
          return result; // 如果找到文件，直接返回路径
        }
      } else if (dirent.isFile()) {
        // 如果是文件，检查是否为目标文件
        if (dirent.name === targetFile) {
          return fullPath; // 找到文件，返回路径
        }
      }
    }
  } catch (err) {
    // 如果读取目录失败，跳过
  }
  return null; // 如果没有找到文件，返回 null
}

let [app, router, mockData] = [new Koa(), new Router(), {}];

app.use(cors());
app.use(bodyParser()); 

app.use(async (ctx) => {
  if (ctx.request.path == "/call") {
    var cli = ctx.request.query?.cli;
    var map = {
      0: "rundll32 sysdm.cpl,EditEnvironmentVariables",
      1: "explorer.exe shell:startup",
    };
    console.log(cli);
    const stdout = await execAsync(map[cli || 0] || `"${cli}"`);
    ctx.body = stdout || "Command executed fail";
    return;
  }
  if (ctx.request.path == "/save") { 
    const { name, content } = ctx.request.body || {};  
    if (!name || !content) {
      ctx.status = 400; 
      ctx.body = { code: 400,msg:"need name and content" }; 
      return;
    } 
    try { 
      fs.writeFileSync(name, content); 
      ctx.body = { code: 200,msg:"OK" }; 
    } catch (error) {
      ctx.status = 500;
      ctx.body = { code: 500,msg: error.message }; 
    }
    return;
  }
  if (ctx.request.path == "/find") {
    // 同步查找文件
    const targetFile = ctx.request.query.file; // 从查询参数中获取文件名
    if (!targetFile) {
      ctx.status = 400;
      ctx.body = { code: 400 };
      return;
    }
    const availableDrives = getAvailableDrives(); // 获取所有可用盘符
    let filePath = null;
    for (const rootDirectory of availableDrives) {
      filePath = traverseDirectorySync(rootDirectory, targetFile);
      if (filePath) {
        break; // 找到文件后退出循环
      }
    }
    ctx.body = { code: filePath ? 200 : 404, filePath };
    return;
  }
  if (ctx.request.path == "/setmock") {
    mockData = ctx.request.body || {};
    ctx.body = "OK";
    return;
  }
  ctx.body = mockData[ctx.request.path] || mockData["/api"] || {};
});
app.use(router.routes()).use(router.allowedMethods());

let app2 = new Koa()
app2.use(cors());
app2.use(bodyParser()); 

app2.use(async (ctx) => {
    ctx.body = mockData[ctx.request.path] || mockData["/api"] || {};
})
app2.use(router.routes()).use(router.allowedMethods());



const app3 = new Koa();  
app3.use(cors());  
// app3 的路由处理
const uploadRouter = new Router();

// 获取用户的文档目录
const userDocumentsDir = path.join(os.homedir(), "Documents", "MyUploads"); // 在文档目录下创建一个 MyUploads 文件夹
if (!fs.existsSync(userDocumentsDir)) fs.mkdirSync(userDocumentsDir, { recursive: true })
const storage = multer.diskStorage({ destination: (req, file, cb) => cb(null, userDocumentsDir), filename: (req, file, cb) =>cb(null, file.originalname), }); 
uploadRouter.post('/upload', multer({ storage, limits:{ fileSize: 9999 * 1024 * 1024, files: 9999 } }).array('files', 9999), async (ctx) => {
  ctx.body = {  success: true,  files: ctx.req.files, };
});
// GET /upload 返回 HTML 页面
uploadRouter.get("/upload", async (ctx) => {
    ctx.body = `
      
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>文件上传测试</title>
</head>
<body>
  <h1>文件上传测试</h1>
  ${ips}
  <form id="uploadForm" enctype="multipart/form-data">
    <input type="file" name="files" multiple>
    <button type="button" onclick="uploadFiles()">上传文件</button>
    <button type="button" onclick="uploadFiles2()">上传文件2</button>
  </form>
  <div id="result"></div> 
  <script>
    async function uploadFiles() { 
      const formData = new FormData(document.getElementById('uploadForm')); 
      try {
        const response = await fetch('http://${ips[0]}:3003/upload', { method: 'POST', body: formData, }); 
        const result = await response.json();
        document.getElementById('result').innerText = JSON.stringify(result, null, 2);
      } catch (error) {
        console.error('上传失败:', error);
        document.getElementById('result').innerText = '上传失败: ' + error.message;
      }
    }
    async function uploadFiles2() { 
      const formData = new FormData(document.getElementById('uploadForm')); 
      try {
        const response = await fetch('http://${ips[1]}:3003/upload', { method: 'POST', body: formData, }); 
        const result = await response.json();
        document.getElementById('result').innerText = JSON.stringify(result, null, 2);
      } catch (error) {
        console.error('上传失败:', error);
        document.getElementById('result').innerText = '上传失败: ' + error.message;
      }
    }
  </script>
</body>
</html>
    `;
});

app3.use(uploadRouter.routes()).use(uploadRouter.allowedMethods()); 

export default ()=>{
    app.listen(3001, () => {
        console.log(`Server is running `);
    });
    app2.listen(3002, () => {
        console.log(`Server is running `);
    });
    app3.listen(3003, () => {
        console.log(`Server is running `);
    });
      
}